package gameHandling;

import gameObject.Hero;
import gameObject.Monster;
import gameObject.effect.BulletEffect;
import gameObject.effect.Effect;

import java.util.Enumeration;
import java.util.Vector;

import javax.microedition.lcdui.Graphics;

import base.RotatableSprite;

import main.PlayingCanvas;
import main.Res;

public class RushHanding extends ExtendHandling {
	int t;
	int leght;
	int level;
	static MonsterRush[][] rushs;
	Vector listMonster;
	Vector listHeroEffect;
	Vector listMonsterEffect;
	Vector listEffect;
	boolean endRush;
	Monster[] nextMonsters;

	public RushHanding(int level) {
		t = 0;
		endRush = false;
		this.level = level;
		listMonster = new Vector();
		listHeroEffect = new Vector();
		listMonsterEffect = new Vector();
		listEffect = new Vector();
		if (rushs == null) {
			intLevel();
		}
		Enumeration vEnum;

		vEnum = PlayingCanvas.getGame().listHero.elements();
		while (vEnum.hasMoreElements()) {
			Hero hero = (Hero) vEnum.nextElement();
			hero.init();
		}
	}

	public void update() {
		
		boolean isEnd = true;
		for (int i = 0; i < rushs[level].length; i++) {
			MonsterRush rush = rushs[level][i];
			if (!rush.isEndRush(t)) {
				isEnd = false;
				if (rush.isRush(t)) {
					Monster monster = rush.getMonster();
					monster.init();
					int r = (level)*30+1;
					if(r>Res.SCR_W){
						r = Res.SCR_W;
					}
					monster.setPosition(Res.SCR_W/2-r/2+Res.getRandom(r), -5);
					listMonster.addElement(monster);
					PlayingCanvas.getGame().addDrawableObject(monster);
				}
			}
		}
		updateListHero();
		updateListMonster();
		updateListEffect();

		if (isEnd && listMonster.isEmpty() && listHeroEffect.isEmpty()
				&& listMonsterEffect.isEmpty() && listEffect.isEmpty()) {
			// TODO end rush level
			int nextLevel = PlayingCanvas.getGame().level+1;
			if(nextLevel == rushs.length || PlayingCanvas.getInstance().isTutorial()){
				PlayingCanvas.getInstance().endRush();
			}else{
			endRush = true;
			}
		}
		t++;
	}
	public void paint(Graphics g) {
		// TODO Auto-generated method stub
		
		if(endRush){
			g.drawImage(Res.IMG_NEXT_LEVEL, 20, 90, Graphics.LEFT|Graphics.TOP);
			boolean []flag = new boolean[]{true,true,true,true,true,true,true};
			if(nextMonsters == null){
				int nextLevel = PlayingCanvas.getGame().level+1;
				int n = rushs[nextLevel].length;
				nextMonsters = new Monster[n];
				for (int i = 0; i < n; i++) {
					nextMonsters[i] =  rushs[nextLevel][i].getMonster();
					
				}
			}
			int k=0;
			for (int i = 0; i < nextMonsters.length; i++) {
				if(flag[nextMonsters[i].getId()]){
					nextMonsters[i].setPosition(120, 140+35*k++);
					nextMonsters[i].paint(g);
					flag[nextMonsters[i].getId()] = false;
				}
			}
		}
		//PlayingCanvas.getInstance().endRush();
	}

	public boolean pointerTaped(int x, int y) {
		if(endRush){
			PlayingCanvas.getInstance().endRush();
		}
		return true;
	}
	private void updateListMonster() {
		Enumeration vEnum;
		vEnum = listMonster.elements();
		Monster monster = null;
		int nR = PlayingCanvas.getGame().tiledMap.getRows();
		while (vEnum.hasMoreElements()) {
			monster = (Monster) vEnum.nextElement();
			monster.update();

			if (monster.getY() >= (nR - 1) * 30 + 10) {
				listMonster.removeElement(monster);
				PlayingCanvas.getGame().removeDrawableObject(monster);
				PlayingCanvas.getInstance().lostLife();
				continue;
			}
			if (monster.hasArm()) {
				Enumeration subVEnum = PlayingCanvas.getGame().listHero
						.elements();
				// boolean inRange = false;
				int x = -1, y = -1;
				double minDist = Double.MAX_VALUE;

				while (subVEnum.hasMoreElements()) {
					Hero hero = (Hero) subVEnum.nextElement();
					if(hero.getHp()<=0){
						continue;
					}
					double dist = monster.dist(hero.getX(), hero.getY());
					if (dist < minDist && dist < monster.getAttackRange()
							&& dist < monster.getViewRange()) {
						x = hero.getX();
						y = hero.getY();
						minDist = dist;
					}
					/*
					 * else { if (!isLine(hero.getX() / 30, hero.getY() / 30,
					 * monster.getX() / 30, monster.getY() / 30)) { continue; }
					 * hero.moveTo(monster.getX(), monster.getY()); }
					 */
					// inRange = true;
				}
				if (minDist < Double.MAX_VALUE) {
					monster.attack(x, y);
				}

				BulletEffect eff = monster.getCurrentEffect();
				if (eff != null) {
					listMonsterEffect.addElement(eff);
					PlayingCanvas.getGame().addDrawableObject(eff);
				}
			}
			if (monster.moveToTarget()) {
				if (monster.isAir()) {
					int bi = monster.getX() / 30;
					int bj = monster.getY() / 30 + 1;
					monster.setTarget(30 * bi + 15, 30 * bj + 15);
				} else {
					int index = PathFinder.findMonsterPath(monster.getX() / 30,
							monster.getY() / 30);
					int bi = index % 8;
					int bj = index / 8;
					monster.setTarget(30 * bi + 15, 30 * bj + 15);
				}
			}

		}
	}

	private void updateListEffect() {
		Enumeration vEnum;
		vEnum = listHeroEffect.elements();
		while (vEnum.hasMoreElements()) {
			BulletEffect eff = (BulletEffect) vEnum.nextElement();
			eff.update();
			if (eff.isDetroyed()) {
				listHeroEffect.removeElement(eff);
				PlayingCanvas.getGame().removeDrawableObject(eff);
			}

			Enumeration subVEnum = listMonster.elements();
			while (subVEnum.hasMoreElements()) {
				Monster monster = (Monster) subVEnum.nextElement();
				if(!eff.isAir() && monster.isAir()){
					continue;
				}
				int dam = eff.hit(monster);
				if (dam > 0) {

					RotatableSprite bloodSpt = Res.createBloodSprite();
					bloodSpt.setRefPixelPosition(
							monster.getX() - 15 + Res.getRandom(22),
							monster.getY() - 15 + Res.getRandom(22));
					Effect bloodEff = new Effect(bloodSpt, 4);

					listEffect.addElement(bloodEff);
					PlayingCanvas.getGame().addDrawableObject(bloodEff);
					monster.incHp(-dam);
					if (monster.getHp() <= 0) {
						listMonster.removeElement(monster);
						PlayingCanvas.getGame().removeDrawableObject(monster);
						PlayingCanvas.getGame().money+= monster.money;
						PlayingCanvas.getInstance().setMessage("+"+monster.money);
					}
				}
			}
		}

		vEnum = listMonsterEffect.elements();
		while (vEnum.hasMoreElements()) {
			BulletEffect eff = (BulletEffect) vEnum.nextElement();
			eff.update();
			if (eff.isDetroyed()) {
				listMonsterEffect.removeElement(eff);
				PlayingCanvas.getGame().removeDrawableObject(eff);
			}

			Enumeration subVEnum = PlayingCanvas.getGame().listHero.elements();
			while (subVEnum.hasMoreElements()) {
				Hero hero = (Hero) subVEnum.nextElement();
				if(hero.getHp() <= 0){
					continue;
				}
				int dam = eff.hit(hero);
				if (dam > 0) {

					RotatableSprite bloodSpt = Res.createBloodSprite();
					bloodSpt.setRefPixelPosition(
							hero.getX() - 15 + Res.getRandom(22), hero.getY()
									- 15 + Res.getRandom(22));
					Effect bloodEff = new Effect(bloodSpt, 4);

					listEffect.addElement(bloodEff);
					PlayingCanvas.getGame().addDrawableObject(bloodEff);
					hero.incHp(-dam);
					if (hero.getHp() <= 0) {
						// listMonster.removeElement(monster);
						Res.PlaySound(1);
						PlayingCanvas.getGame().removeDrawableObject(hero);
						hero.resetRepawnTime();
					}
				}
			}
		}

		vEnum = listEffect.elements();
		while (vEnum.hasMoreElements()) {
			Effect eff = (Effect) vEnum.nextElement();
			eff.update();
			if (eff.isDetroyed()) {
				listEffect.removeElement(eff);
				PlayingCanvas.getGame().removeDrawableObject(eff);
			}
		}
	}

	private void updateListHero() {
		Enumeration vEnum;

		vEnum = PlayingCanvas.getGame().listHero.elements();
		while (vEnum.hasMoreElements()) {
			Hero hero = (Hero) vEnum.nextElement();
			hero.update();
			if(hero.getHp()<=0){
				if(hero.countRepawnTime()){
					hero.init();
					hero.idle();
					Res.PlaySound(2);
					PlayingCanvas.getGame().addDrawableObject(hero);
				}
				continue;
			}
			Enumeration subVEnum = listMonster.elements();
			boolean inRange = false;
			while (subVEnum.hasMoreElements()) {
				Monster monster = (Monster) subVEnum.nextElement();
				if (hero.inRange(monster)) {
					if (hero.dist(monster.getX(), monster.getY()) < hero
							.getAttackRange()) {
						hero.attack(monster.getX(), monster.getY());
					} else {
						if (!PathFinder.isLine(hero.getX() / 30, hero.getY() / 30,
								monster.getX() / 30, monster.getY() / 30)) {
							continue;
						}
						hero.moveTo(monster.getX(), monster.getY());
					}
					inRange = true;
					break;
				}
			}
			if (!inRange) {
				hero.moveToSettle();
			}

			BulletEffect eff = hero.getCurrentEffect();
			if (eff != null) {
				Res.PlaySound(0);
				listHeroEffect.addElement(eff);
				PlayingCanvas.getGame().addDrawableObject(eff);
			}
		}
	}


	public static void intLevel() {
		rushs = new MonsterRush[20][];
		int level = -1;
		int iRush;
		// LEVEL 1
		rushs[++level] = new MonsterRush[1];
		iRush = 0;
		rushs[level][iRush++] = new MonsterRush(3, -1, -1, 0, 1, 0, 35, 5);

		// LEVEL 2
		rushs[++level] = new MonsterRush[1];
		iRush = 0;
		rushs[level][iRush++] = new MonsterRush(1, -1, -1, 0, 2, 0, 40, 10);

		// LEVEL 3
		rushs[++level] = new MonsterRush[1];
		iRush = 0;
		rushs[level][iRush++] = new MonsterRush(2, -1, -1, 0,3, 0, 40, 10);

		// LEVEL 4
		rushs[++level] = new MonsterRush[1];
		iRush = 0;
		rushs[level][iRush++] = new MonsterRush(4, -1, -1, 0, 5, 0, 25, 5);
		
		// LEVEL 5
		rushs[++level] = new MonsterRush[3];
		iRush = 0;
		rushs[level][iRush++] = new MonsterRush(1, 16, -1, 0, 8, 0, 1, 2);
		rushs[level][iRush++] = new MonsterRush(1, 16, -1, 0, 8, 40, 1, 3);
		rushs[level][iRush++] = new MonsterRush(3, 16, -1, 1, 10, 80, 25, 5);
		
		// LEVEL 6
		rushs[++level] = new MonsterRush[2];
		iRush = 0;
		rushs[level][iRush++] = new MonsterRush(1, -1, -1, 1, 15, 0, 30, 10);
		rushs[level][iRush++] = new MonsterRush(1, -1, 22, 1, 15, 250, 30, 10);
		
		// LEVEL 7
		rushs[++level] = new MonsterRush[1];
		iRush = 0;
		rushs[level][iRush++] = new MonsterRush(3, 19, -1, 2, 10, 0, 20, 15);

		// LEVEL 8
		rushs[++level] = new MonsterRush[3];
		iRush = 0;
		rushs[level][iRush++] = new MonsterRush(1, 17, -1, 2, 20, 0, 1, 3);
		rushs[level][iRush++] = new MonsterRush(1, 17, -1, 2, 20, 80, 1, 3);
		rushs[level][iRush++] = new MonsterRush(1, 17, -1, 2, 20, 160, 1, 3);
		//rushs[level][iRush++] = new MonsterRush(1, 16, 22, 2, 30, 300, 35, 10);
		
		// LEVEL 9
		rushs[++level] = new MonsterRush[2];
		iRush = 0;
		rushs[level][iRush++] = new MonsterRush(1, 17, 22, 2, 30, 0, 35, 6);
		rushs[level][iRush++] = new MonsterRush(5, -1, -1, 1, 20, 15, 35, 6);
		
		// LEVEL 10
		rushs[++level] = new MonsterRush[1];
		iRush = 0;
		rushs[level][iRush++] = new MonsterRush(2, -1, 22, 3, 40, 0, 15, 20);
		//rushs[level][iRush++] = new MonsterRush(2, -1, 22, 3, 60, 10, 20, 10);
		//rushs[level][iRush++] = new MonsterRush(2, -1, -1, 3, 40, 60, 15, 10);

		// LEVEL 11
		rushs[++level] = new MonsterRush[1];
		iRush = 0;
		rushs[level][iRush++] = new MonsterRush(6, -1, -1, 2, 50, 0, 30, 15);
		
		// LEVEL 12
		rushs[++level] = new MonsterRush[2];
		iRush = 0;
		rushs[level][iRush++] = new MonsterRush(3, 16, 22, 4, 65, 0, 20, 10);
		rushs[level][iRush++] = new MonsterRush(3, 19, 22, 4, 65, 10, 20, 10);
		
		
		// LEVEL 13
		rushs[++level] = new MonsterRush[3];
		iRush = 0;
		rushs[level][iRush++] = new MonsterRush(4, -1, -1, 4, 50, 0, 30, 10);
		rushs[level][iRush++] = new MonsterRush(5, -1, -1, 4, 60, 10, 30, 10);
		rushs[level][iRush++] = new MonsterRush(6, -1, -1, 4, 70, 50, 30, 10);
		
		// LEVEL 14
		rushs[++level] = new MonsterRush[3];
		iRush = 0;
		rushs[level][iRush++] = new MonsterRush(1, 17, 23, 4, 80, 0, 20, 10);
		rushs[level][iRush++] = new MonsterRush(1, 20, 23, 4, 80, 100, 20, 10);
		rushs[level][iRush++] = new MonsterRush(3, 19, 23, 4, 80, 200, 20, 10);
		
		// LEVEL 15
		rushs[++level] = new MonsterRush[4];
		iRush = 0;
		rushs[level][iRush++] = new MonsterRush(3, 16, 23, 5, 90, 0, 15, 10);
		rushs[level][iRush++] = new MonsterRush(3, 19, 23, 5, 90, 100, 15, 10);
		rushs[level][iRush++] = new MonsterRush(2, -1, -1, 5, 90, 200, 15, 10);
		rushs[level][iRush++] = new MonsterRush(4, -1, -1, 6, 90, 30, 50, 10);
		
		// LEVEL 16
		rushs[++level] = new MonsterRush[4];
		iRush = 0;
		rushs[level][iRush++] = new MonsterRush(1, 17, 24, 6, 100, 0, 1, 8);
		rushs[level][iRush++] = new MonsterRush(1, 17, 24, 6, 100, 50, 1, 8);
		rushs[level][iRush++] = new MonsterRush(1, 17, 24, 6, 100, 100, 1, 8);
		rushs[level][iRush++] = new MonsterRush(1, 17, 24, 6, 100, 150, 1, 8);
		
		// LEVEL 17
		rushs[++level] = new MonsterRush[2];
		iRush = 0;
		rushs[level][iRush++] = new MonsterRush(2, -1, 23, 7, 110, 0, 12, 20);
		rushs[level][iRush++] = new MonsterRush(2, -1, 23, 7, 110, 1, 12, 20);
		
		
		// LEVEL 18
		rushs[++level] = new MonsterRush[4];
		iRush = 0;
		rushs[level][iRush++] = new MonsterRush(1, 18, 24, 8, 130, 30, 30, 10);
		rushs[level][iRush++] = new MonsterRush(1, 18, 24, 8, 130, 30, 30, 10);
		rushs[level][iRush++] = new MonsterRush(6, -1, -1, 7, 120, 0, 30, 15);
		rushs[level][iRush++] = new MonsterRush(6, -1, -1, 7, 120, 0, 30, 15);
		
		// LEVEL 19
		rushs[++level] = new MonsterRush[5];
		iRush = 0;
		rushs[level][iRush++] = new MonsterRush(3, 21, -1, 9, 160, 0, 30, 10);
		rushs[level][iRush++] = new MonsterRush(1, 18, 24, 9, 160, 0, 30, 10);
		rushs[level][iRush++] = new MonsterRush(1, 18, 24, 9, 160, 0, 30, 10);
		rushs[level][iRush++] = new MonsterRush(2, -1, 25, 9, 150, 3, 30, 10);
		rushs[level][iRush++] = new MonsterRush(2, -1, 25, 9, 150, 3, 30, 10);
		//33000
		// LEVEL 20
		rushs[++level] = new MonsterRush[7];
		iRush = 0;
		rushs[level][iRush++] = new MonsterRush(1, 18, 24, 10, 160, 0, 40, 10);
		rushs[level][iRush++] = new MonsterRush(1, 18, 24, 10, 160, 0, 40, 10);
		rushs[level][iRush++] = new MonsterRush(3, 21, 24, 10, 170, 0, 40, 10);
		rushs[level][iRush++] = new MonsterRush(2, -1, 25, 10, 160, 100, 25, 10);
		rushs[level][iRush++] = new MonsterRush(2, -1, 25, 10, 160, 100, 25, 10);
		rushs[level][iRush++] = new MonsterRush(5, -1, -1, 10, 180, 0, 40, 10);
		rushs[level][iRush++] = new MonsterRush(6, -1, -1, 10, 200, 100, 25, 10);
	}

}
